/*838. 堆排序

输入一个长度为 n的整数数列，从小到大输出前 m小的数。
输入格式
第一行包含整数 n和 m
第二行包含 n个整数，表示整数数列。

输出格式
共一行，包含 m个整数，表示整数数列中前 m小的数。

数据范围
1≤m≤n≤105，1≤数列中元素≤109
输入样例：
5 3
4 5 1 3 2
输出样例：
1 2 3*/
#include<iostream>
#include<algorithm>//swap(a,b)
using namespace std;
const int N = 100010, M = 100010;
int h[N], sz;//size:存储元素的个数以及最后一个元素的下标
int down(int u) //U:下标，不要传成h[u]啦
{
    int t = u;
    //左边小，右边大，交换左边
    //左边小，右边比左边还小，先交换左边，然后交换右边
    if (u * 2 <= sz && h[u * 2] < h[t]) t = u * 2;//左小
    if (u * 2 + 1 <= sz && h[u * 2 + 1] < h[t]) t = u * 2 + 1;//右小
    if (u != t)
    {
        swap(h[u], h[t]); ////swap(u,t);
        down(t);
    }
}
int main()
{
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++)   cin >> h[i]; //这个输入数据怎么老是忘记嘞
    sz = n;
    //得先排一下：
    for (int i = n / 2; i; i--)    down(i);
    while (m--)
    {
        cout << h[1] << " ";
        h[1] = h[sz];
        sz--;
        down(1);
    }
    return 0;
}

/*总结：
1.为什么down()内还需要down(t);进行递归？
   交换数值后，t这个结点存储原本u的值，u存储存储t的值（三个数中的最小值）。
   u不用调整了，但t情况不明，可能需要调整。直到它比左右子节点都小
   比如：5 3 6 4 5=》3 5 6 4 5，交换过后发现5的左孩子4比5小，就还需要递归交换下去，
   递归的终止条件也就是不满足if(),即不再需要交换的时候了
2.如何手写一个堆--步骤
    *插入一个数
    *求集合当中的最小值 --》h[++size]=x,up(size)
    *删除最小值  --》h[1]=h[size],size--,down(1)
    *删除任意一个元素  --》h[x]=h[size],size--,down(x),up(x)
    *修改任意一个元素  --》h[x]=m,down(m),up(m)
3.如何存储堆：用一位数组存储，x,2*x(左孩子），2*x+1(右孩子）*/
/*
1.down函数中应该 先判断边界再判断值大小 ，若写成下面这样，会越界
    if (h[t] > h[2 * i] && 2 * i <= n) t = 2 * i; 
    if (h[t] > h[2 * i + 1] && 2 * i + 1 <= n) t = 2 * i + 1;
    需改成如下：
    if (2 * i <= n && h[t] > h[2 * i]) t = 2 * i; 
    if (2 * i + 1 <= n && h[t] > h[2 * i + 1]) t = 2 * i + 1;如果已经越界，就不会再访问数组了。段错误就是数组越界造成的

2.    这两步骤在做的时候忘记了：
    sz=n;
    for(int i=n/2;i;i--)   down(i);*/

    /*解题的话：直接sort()一下输出就可以
    int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=0;i<n;i++)    cin>>h[i];
    sort(h,h+n,less<int>());//sort(num,num+10,greater<int>());
    for(int i=0;i<m;i++)
    {
        cout<<h[i]<<" ";
    }
}*/